package com.ctshk.common.utils.process;

import com.ctshk.common.utils.anno.ColumnMapping;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description 字典處理
 * @Author wansi <gaylen15527491065@yeah.net>
 * @Date 2021/4/12
 */
public class ProcessorUtil {

    /**
     * 字典<k，v></k，v>
     * 通過註解配置設置字典值串
     * @param t
     * @param clazz
     * @param <T>
     */
    public static final <T> void  process(T t,Class<?> clazz){

        ReflectionUtils.doWithFields(clazz, field -> {
            if(field.isAnnotationPresent(ColumnMapping.class)){
                ColumnMapping annotation = field.getAnnotation(ColumnMapping.class);
                String fieldId = annotation.fieldId();
                String[] mapping = annotation.mapping();

                if(mapping.length <= 0 || mapping.length % 2 != 0){
                    throw new RuntimeException("ColumnMapping mapping length mod 2 not 0");
                }

                AtomicInteger radixCount = new AtomicInteger(0);
                AtomicInteger evenCount = new AtomicInteger(0);

                Map<Object,Object> radix = new LinkedHashMap<>();
                Map<Object,Object> even = new LinkedHashMap<>();
                Map<Object,Object> finalMap = new LinkedHashMap<>();

                for(int i = 0; i < mapping.length ; i++){
                    if((i+1)%2==0){
                        even.put(radixCount.getAndIncrement(),mapping[i]);
                    }else {
                        radix.put(evenCount.getAndIncrement(),mapping[i]);
                    }
                }
                radix.forEach((k,v)->{
                    finalMap.put(v,even.get(k));
                });

                //ID字段
                Field fieldID = ReflectionUtils.findField(clazz, fieldId);
                ReflectionUtils.makeAccessible(fieldID);
                Object value = fieldID.get(t);
                ReflectionUtils.makeAccessible(field);
                field.set(t,value == null ? "-" : finalMap.get(value.toString()));
            }
        });
    }

    public static final <T> void  processMore(List<T> list, Class<?> clazz){
        list.forEach(entity->{
            process(entity,clazz);
        });
    }
}
